package com.yunchang.spring.visitor.demo.service;

import com.yunchang.spring.visitor.core.handler.response.DownloadHandler;
import com.yunchang.spring.visitor.core.paramtype.HeaderParamsMap;
import com.yunchang.spring.visitor.core.paramtype.UrlParamsMap;
import com.yunchang.spring.visitor.demo.model.MyDataType;
import com.yunchang.spring.visitor.demo.model.MyJsonObject;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

/**
 * 测试Service。
 * 支持反射调用该Service的m1,m2,m3方法。
 * Created by jasontujun on 2018/1/11.
 */
@Service
public class TestService implements ITestService, IDownloadService {

    /**
     * 反射调用该方法，没有参数
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m0
     */
    @Override
    public String m0() {
        return "invoke method without params";
    }

    /**
     * 反射调用该方法，参数默认有且只有一个，类型为Map
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m1?p1=123
     */
    @Override
    public String m1(Map<String, String> params) {
        return params.get("p1") + "_suffix";
    }

    /**
     * 使用别名，反射调用该方法，参数默认有且只有一个，类型为Map
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/alias?p1=123
     */
    @Override
    public String m1Alias(Map<String, String> params) {
        return m1(params);
    }

    /**
     * 反射调用该方法，参数自动填充到aa和bb
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m2?aa=12&bb=23
     */
    @Override
    public Map m2(final String aa, final Integer bb) {
        return new HashMap<String, String>() {{
            put("key", aa + "_" + bb);
        }};
    }

    /**
     * 反射调用该方法，参数自动填充到aa、bb和cc，其中cc为自定义类型
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/m3?aa=12&bb=23&cc=hello,world
     */
    @Override
    public Map m3(String aa, Integer bb, MyDataType cc) {
        return new HashMap() {{
            put("aa", aa);
            put("bb", bb);
            put("cc", cc);
        }};
    }

    @Override
    public String m4(HeaderParamsMap header, UrlParamsMap url, HttpMethod method, Map params, InputStream stream) {
        return "true";
    }

    @Override
    public String m5(final String aa, HttpMethod method, HeaderParamsMap header, UrlParamsMap url,
                     final Integer bb, InputStream stream, final String cc) {
        return "true";
    }

    /**
     * 无法反射调用该方法，因为注解的参数列表和实际方法声明的参数列表不一致。
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/error?aa=123&bb=789
     */
    @Override
    public String error(String aa, String bb, String cc) {
        // 注解参数和实际方法参数不一致，无法阿调用
        return aa + "_" + bb + "cc";
    }

    @Override
    public String error2(HeaderParamsMap header, String aa, Integer bb) {
        // params未定义 但是实际参数想拆分
        return aa + "_" + bb;
    }

    /**
     * 无法反射调用该方法，因为没有加注解
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/normal?a=123&b=789
     */
    public String normal(Map<String, String> params) {
        return params.get("param2") + "_suffix";
    }


    @Override
    public String json0() {
        return "invoke method without params by post json";
    }

    @Override
    public String json1(String json) {
        return json;
    }

    @Override
    public Map json2(Map jsonMap) {
        return jsonMap;
    }

    @Override
    public String json3(HttpMethod method, HeaderParamsMap header, String json, UrlParamsMap url) {
        return "invoke method with params=" + json + " by [" + method+ "] json.";
    }

    @Override
    public String json4(HttpMethod method, HeaderParamsMap header, UrlParamsMap url) {
        return "invoke method by [" + method+ "] json.";
    }

    @Override
    public Map json5(HttpMethod method, final String aa, HeaderParamsMap header,
                     final Integer bb, UrlParamsMap url, MyJsonObject cc) {
        return new HashMap() {{
            put("aa", aa);
            put("bb", bb);
            put("cc", cc);
        }};
    }

    @Override
    public String jsonError(HttpMethod method, HeaderParamsMap header, String json, UrlParamsMap url, InputStream inputStream) {
        return "invoke method with params=" + json + " by [" + method+ "] json. InputStream=" + inputStream;
    }

    /**
     * 反射调用该方法，并缓存方法返回结果，下次用同样参数调用该方法，优先查询缓存。
     * 测试链接 {@link}http://127.0.0.1:8080/v1/service/cache?cc=111&dd=2222
     */
    @Override
    public Map cache(final String cc, final int dd) {
        return new HashMap<String, String>() {{
            put("key", cc + "#" + dd);
        }};
    }

    @Override
    public Map jsonCache1(String json) {
        return new HashMap<String, String>() {{
            put("key", json);
        }};
    }

    @Override
    public Map jsonCache2(String cc, int dd) {
        return new HashMap<String, String>() {{
            put("key", cc + "#" + dd);
        }};
    }


    /**
     * 反射调用该方法，提供文件下载
     * 测试链接 {@link}http://127.0.0.1:8080/download/service/file?name=download.txt
     *
     * @see DownloadHandler
     */
    @Override
    public Map file(Map<String, String> params) {
        String fileName = params.get("name");
        if (StringUtils.isEmpty(fileName)) {
            throw new IllegalArgumentException("Download error, file name is null!");
        }
        Map result = new HashMap();
        result.put(DownloadHandler.KEY_INPUT_STREAM, Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName));
        result.put(DownloadHandler.KEY_FILE_NAME, fileName);
        return result;
    }
}
